Skip to content

Add transform gizmo (move/rotate/scale)#173

Open
iammojogo-sudo wants to merge 17 commits into
lightningpixel:devfrom
iammojogo-sudo:main
Open

Add transform gizmo (move/rotate/scale)#173
iammojogo-sudo wants to merge 17 commits into
lightningpixel:devfrom
iammojogo-sudo:main

Conversation

@iammojogo-sudo

Copy link
Copy Markdown

Closes #161

Adds a gizmo to move/rotate/scale the mesh in the viewport. Shows when the
mesh is selected, W/E/R to switch modes. Apply bakes it into the GLB so it
sticks on export, Reset reverts.

New /optimize/transform endpoint on the backend handles the bake.

Tested locally, works.

@lightningpixel lightningpixel changed the base branch from main to dev June 9, 2026 08:53
@lightningpixel

lightningpixel commented Jun 9, 2026

Copy link
Copy Markdown
Owner

You’ll need to resolve the conflicts on the PR

Edit:
And I added the new toolbar on the Generate page.
So instead of putting the buttons in the bar on the left side, you should use the second toolbar at the top.
I already added the transform buttons there. You’ll just need to adapt it

@lightningpixel

Copy link
Copy Markdown
Owner

The pushed branch isn't in a working state, so I have to request changes.

Blocking issues

  1. The branch doesn't run. Viewer3D.tsx uses gizmoMode, setGizmoMode, applying, resetToken, and meshObject but never declares them (no useState), and TransformControls is used without being imported from @react-three/drei. Running the app immediately
    throws Uncaught ReferenceError: setGizmoMode is not defined, and npm run build fails type-checking. It looks like part of your wiring commit was lost before pushing — could you push the complete version you actually tested?

  2. api/routers/optimize.py contains the entire module twice (paste/merge accident — router = APIRouter appears at lines 25 and 361, every endpoint is defined twice). The second router shadows the first, and since it's the old copy without /transform, the new
    endpoint is never registered: every "Apply" call will 404. Please reduce the file to a single copy that includes /transform.

  3. Gizmo wiring is incomplete. MeshModelProps declares onObject but MeshModel never calls it, so meshObject would stay null and the gizmo would never render. SceneMeshModel reads autoCenter and resetToken but those props are never added to its signature nor
    passed down.

  4. Out-of-scope changes — please remove these from the PR:

    • The README "Sponsors" section and the X/Twitter links. Sponsor recognition is a maintainer decision; adding yourself there isn't something we can merge from a feature PR.
    • The version bumps in package.json and api/main.pydev has already moved to 0.3.6 independently, so this will conflict anyway.

Smaller things to fix in the same pass

  • The {stem}_xf.glb output name means re-applying produces ..._xf_xf.glb, and applying twice from the same base overwrites the file while keeping the same URL — useGLTF's cache will then show the stale mesh. A unique suffix (we already use uuid elsewhere) would avoid
    both problems.
  • /transform reimplements its path check inline — please reuse _resolve_input_path like /mesh and /smooth do.
  • handleApplyTransform has no catch, so a backend failure is silent for the user.
  • The baked matrix includes the auto-centering offset applied on load, so "Apply" permanently moves the file's origin even for a pure rotation. If that's intentional ("bake what you see"), a comment explaining it would help.
  • The W/E/R/Escape handler only guards against HTMLInputElement/HTMLTextAreaElement — contenteditable elements would still trigger mode switches.
  • useApi.ts uses tab indentation against the file's spaces, and importMesh was re-indented without changes — this will fail npm run lint.

Happy to re-review once the complete, building version is pushed. Thanks again for the contribution !

@iammojogo-sudo

Copy link
Copy Markdown
Author

The pushed branch isn't in a working state, so I have to request changes.

Blocking issues

1. **The branch doesn't run.** `Viewer3D.tsx` uses `gizmoMode`, `setGizmoMode`, `applying`, `resetToken`, and `meshObject` but never declares them (no `useState`), and `TransformControls` is used without being imported from `@react-three/drei`. Running the app immediately
   throws `Uncaught ReferenceError: setGizmoMode is not defined`, and `npm run build` fails type-checking. It looks like part of your wiring commit was lost before pushing — could you push the complete version you actually tested?

2. **`api/routers/optimize.py` contains the entire module twice** (paste/merge accident — `router = APIRouter` appears at lines 25 and 361, every endpoint is defined twice). The second `router` shadows the first, and since it's the old copy without `/transform`, the new
   endpoint is never registered: every "Apply" call will 404. Please reduce the file to a single copy that includes `/transform`.

3. **Gizmo wiring is incomplete.** `MeshModelProps` declares `onObject` but `MeshModel` never calls it, so `meshObject` would stay `null` and the gizmo would never render. `SceneMeshModel` reads `autoCenter` and `resetToken` but those props are never added to its signature nor
   passed down.

4. **Out-of-scope changes** — please remove these from the PR:
   
   * The README "Sponsors" section and the X/Twitter links. Sponsor recognition is a maintainer decision; adding yourself there isn't something we can merge from a feature PR.
   * The version bumps in `package.json` and `api/main.py` — `dev` has already moved to 0.3.6 independently, so this will conflict anyway.

Smaller things to fix in the same pass

* The `{stem}_xf.glb` output name means re-applying produces `..._xf_xf.glb`, and applying twice from the same base overwrites the file while keeping the same URL — `useGLTF`'s cache will then show the stale mesh. A unique suffix (we already use `uuid` elsewhere) would avoid
  both problems.

* `/transform` reimplements its path check inline — please reuse `_resolve_input_path` like `/mesh` and `/smooth` do.

* `handleApplyTransform` has no `catch`, so a backend failure is silent for the user.

* The baked matrix includes the auto-centering offset applied on load, so "Apply" permanently moves the file's origin even for a pure rotation. If that's intentional ("bake what you see"), a comment explaining it would help.

* The W/E/R/Escape handler only guards against `HTMLInputElement`/`HTMLTextAreaElement` — contenteditable elements would still trigger mode switches.

* `useApi.ts` uses tab indentation against the file's spaces, and `importMesh` was re-indented without changes — this will fail `npm run lint`.

Happy to re-review once the complete, building version is pushed. Thanks again for the contribution !

Not a worry, thank you and Ill work on this today until its ready. Sorry for the extra work. I hope to reduce that soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FEATURE 1 - Interactive transform gizmo

4 participants